package main

import (
	"context"  // 导入上下文包，用于控制请求的超时和取消
	"fmt"      // 导入格式化包，用于输出信息
	"net/http" // 导入HTTP包，用于定义HTTP状态码和响应

	"github.com/gin-gonic/gin"     // 导入Gin框架，用于快速构建Web应用
	"github.com/go-redis/redis/v8" // 导入Redis客户端库，支持Go模块
)

var ctx = context.Background() // 创建一个背景上下文，用于Redis操作

func main() {
	// 初始化Redis客户端，连接到指定的Redis服务器
	rdb := redis.NewClient(&redis.Options{
		Addr:     "192.168.1.4:6379", // Redis服务器地址
		Password: "",                 // Redis没有设置密码
		DB:       0,                  // 使用默认的数据库（编号0）
	})

	// 测试Redis连接是否成功
	if pong, err := rdb.Ping(ctx).Result(); err != nil {
		panic(err) // 连接失败则抛出异常
	} else {
		fmt.Println("Redis ping response:", pong) // 输出Ping的响应
	}

	// 创建一个默认的Gin路由引擎
	r := gin.Default()
	// 加载所有模板文件
	r.LoadHTMLGlob("templates/*")

	// 注册页面
	r.GET("/register", func(c *gin.Context) {
		c.HTML(http.StatusOK, "register.html", nil)
	})

	// 登录页面
	r.GET("/login", func(c *gin.Context) {
		c.HTML(http.StatusOK, "login.html", nil)
	})

	// 处理注册请求
	r.POST("/register", func(c *gin.Context) {
		username := c.PostForm("username") // 获取提交的用户名
		password := c.PostForm("password") // 获取提交的密码
		if username == "" || password == "" {
			// 用户名或密码为空，返回错误信息
			c.JSON(http.StatusBadRequest, gin.H{"error": "用户名和密码不能为空"})
			return
		}
		// 检查用户名是否已存在
		exists, err := rdb.Exists(ctx, "user:"+username).Result()
		if err != nil {
			// Redis操作出错，返回错误
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		if exists == 1 {
			// 用户名已存在，提示用户
			c.HTML(http.StatusOK, "register.html", gin.H{"error": "用户名已存在"})
			return
		}
		// 将用户名和密码存入Redis哈希表
		err = rdb.HSet(ctx, "user:"+username, "password", password).Err()
		if err != nil {
			// 存储出错，返回错误
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		// 注册成功，跳转到登录页面并提示
		c.HTML(http.StatusOK, "login.html", gin.H{"message": "注册成功，请登录"})
	})

	// 处理登录请求
	r.POST("/login", func(c *gin.Context) {
		username := c.PostForm("username") // 获取提交的用户名
		password := c.PostForm("password") // 获取提交的密码
		if username == "" || password == "" {
			// 用户名或密码为空，提示用户
			c.HTML(http.StatusOK, "login.html", gin.H{"error": "用户名和密码不能为空"})
			return
		}
		// 从Redis中获取存储的密码
		storedPassword, err := rdb.HGet(ctx, "user:"+username, "password").Result()
		if err == redis.Nil {
			// 用户不存在
			c.HTML(http.StatusOK, "login.html", gin.H{"error": "用户不存在"})
			return
		} else if err != nil {
			// Redis操作出错
			c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
			return
		}
		// 比较密码是否一致
		if storedPassword != password {
			// 密码错误
			c.HTML(http.StatusOK, "login.html", gin.H{"error": "密码错误"})
			return
		}
		// 登录成功，显示成功信息
		c.HTML(http.StatusOK, "login.html", gin.H{"message": "登录成功"})
	})

	// 启动Web服务器，监听80端口
	r.Run(":80")
}
